/*
    Copyright 2006 Andrew Wilkinson <andrew@indiegigs.co.uk>

    This file is part of GL2x.

    GL2x is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    GL2x is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with GL2x; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "gl_internal.h"

unsigned char Vector_eq(Vector this, Vector other) {
    return Fixed_eq(this.e[0], other.e[0]) && Fixed_eq(this.e[1], other.e[1]) && Fixed_eq(this.e[2], other.e[2]) && Fixed_eq(this.e[3], other.e[3]);
}

Vector Vector_sub(Vector this, Vector other) {
    Vector r;

    r.e[0] = Fixed_sub(this.e[0], other.e[0]);
    r.e[1] = Fixed_sub(this.e[1], other.e[1]);
    r.e[2] = Fixed_sub(this.e[2], other.e[2]);
    r.e[3] = Fixed_sub(this.e[3], other.e[3]);

    return r;
}

Vector Vector_mul(Vector this, Fixed other) {
    Vector r;

    r.e[0] = Fixed_mul(this.e[0], other);
    r.e[1] = Fixed_mul(this.e[1], other);
    r.e[2] = Fixed_mul(this.e[2], other);
    r.e[3] = Fixed_mul(this.e[3], other);

    return r;
}

Vector Vector_div(Vector this, Fixed other) {
    Vector r;

    r.e[0] = Fixed_div(this.e[0], other);
    r.e[1] = Fixed_div(this.e[1], other);
    r.e[2] = Fixed_div(this.e[2], other);
    r.e[3] = Fixed_div(this.e[3], other);

    return r;
}

Vector Vector_divi(Vector this, int other) {
    Vector r;

    r.e[0] = Fixed_divi(this.e[0], other);
    r.e[1] = Fixed_divi(this.e[1], other);
    r.e[2] = Fixed_divi(this.e[2], other);
    r.e[3] = Fixed_divi(this.e[3], other);

    return r;
}

Vector Vector_cross(Vector this, Vector other) {
    Vector r;

    r.e[0] = Fixed_sub(Fixed_mul(this.e[1], other.e[2]), Fixed_mul(this.e[2], other.e[1]));
    r.e[1] = Fixed_sub(Fixed_mul(this.e[2], other.e[0]), Fixed_mul(this.e[0], other.e[2]));
    r.e[2] = Fixed_sub(Fixed_mul(this.e[0], other.e[1]), Fixed_mul(this.e[1], other.e[0]));
    r.e[3] = Fixed_one;

    return r;
}

Vector Vector_normalize(Vector this) {
    Fixed l = Vector_length(this);

    Vector r;
    r.e[0] = Fixed_div(this.e[0], l);
    r.e[1] = Fixed_div(this.e[1], l);
    r.e[2] = Fixed_div(this.e[2], l);
    r.e[3] = Fixed_one;

    return r;
}

Fixed Vector_length(Vector this) {
    return Fixed_sqrt(Fixed_add(Fixed_add(Fixed_mul(this.e[0], this.e[0]), Fixed_mul(this.e[1], this.e[1])), Fixed_mul(this.e[2], this.e[2])));
}
